/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import * as path from 'path'
import { existsSync } from 'fs'
import Handlebars from 'handlebars'
import { PluginConfig, RouterMap, TemplateModel } from './models'
import { EtsAnalyzer } from './utils/EtsAnalyzer'
import { FileManager } from './utils/FileManager'
import { CONSTANTS } from './utils/Constants'
import { logger } from './utils/Logger'

// 路由插件主类
export class RouterPlugin {
  private config: PluginConfig;
  private fileManager: FileManager;

  constructor(config: PluginConfig) {
    this.config = config;
    this.fileManager = new FileManager(config);
    this.initConfig();
  }

  private initConfig() {
    this.config.annotation = CONSTANTS.ROUTER_ANNOTATION_NAME;
    this.config.builderTpl = CONSTANTS.ROUTER_BUILDER_TEMPLATE;
    this.config.routerMapDir = CONSTANTS.ROUTER_MAP_PATH;
    this.config.builderDir = CONSTANTS.ROUTER_BUILDER_PATH;
    this.config.builderFileName = CONSTANTS.ROUTER_BUILDER_NAME;
  }

  // 主执行方法
  execute() {
    logger.info(`执行插件 ${CONSTANTS.PLUGIN_ID}...`, 'RouterPlugin');
    logger.debug(`节点: ${this.config.moduleName}, 路径: ${this.config.modulePath}`, 'RouterPlugin');
    
    const templateModel: TemplateModel = {
      viewList: [],
    };
    const routerMap: RouterMap = {
      routerMap: [],
    };
    
    try {
      const defaultDir = 'src/main/ets/components';
      if (!this.config.scanDirs) {
        this.config.scanDirs = [defaultDir];
      } else if (!this.config.scanDirs.includes(defaultDir)) {
        this.config.scanDirs.push(defaultDir);
      }
      
      let allFiles = new Set(this.config.scanFiles);
      this.config.scanDirs.forEach((dir) => {
        let dirPath = `${this.config.modulePath}/${dir}`;
        const filesArr = this.fileManager.getFiles(dirPath);
        allFiles = new Set([...allFiles, ...filesArr]);
      });
      
      logger.debug(`找到 ${allFiles.size} 个文件进行扫描`, 'RouterPlugin');
      
      allFiles.forEach((sourcePath) => {
        if (!sourcePath.endsWith('.ets')) {
          sourcePath = sourcePath + '.ets';
        }
        
        const importPath = path
          .relative(`${this.config.modulePath}/${this.config.builderDir}`, sourcePath)
          .replaceAll('\\', '/')
          .replaceAll('.ets', '');
          
        const analyzer = new EtsAnalyzer(this.config, sourcePath);
        analyzer.start();
        
        if (analyzer.routerAnnotationExisted) {
          logger.debug(`解析到路由装饰器: ${sourcePath}`, 'RouterPlugin');
          
          let paramVal: string = '{\n\t\t';
          analyzer.analyzeResult.param.forEach(
            (v, k) => (paramVal += `${k}: ${v},`)
          );
          paramVal = paramVal.slice(0, -1);
          paramVal = paramVal.replace(/,/g, ',\n\t\t');
          paramVal += '\n\t}';

          templateModel.viewList.push({
            viewName: analyzer.analyzeResult.viewName,
            importPath: importPath,
            functionName: analyzer.analyzeResult.functionName,
            param: 'param?: ESObject',
            paramVal: analyzer.analyzeResult.param.size ? paramVal : '',
            title: analyzer.analyzeResult.title,
            hideTitleBar: this.config.hideTitleBar,
          });
          
          routerMap.routerMap.push({
            name: analyzer.analyzeResult.name,
            pageModule: this.config.moduleName,
            pageSourceFile: `${this.config.builderDir}/${this.config.builderFileName}`,
            registerFunction: `${analyzer.analyzeResult.functionName}Register`,
            auth: analyzer.analyzeResult.auth || false,
            hideTitleBar: this.config.hideTitleBar,
          });
        }
      });
      
      logger.info(`找到 ${routerMap.routerMap.length} 个路由配置`, 'RouterPlugin');
      logger.debug(`路由表: ${JSON.stringify(routerMap, null, 2)}`, 'RouterPlugin');
      
      // 生成路由方法文件
      this.generateBuilder(templateModel);
      // 生成路由表文件
      this.generateRouterMap(routerMap);
      // 生成title配置文件
      this.generateTitleConfig(templateModel);
      // 生成Index.ets文件
      this.generateIndex();
      
      logger.info('路由生成完成', 'RouterPlugin');
    } catch (err) {
      logger.error(`插件执行出错: ${err.message}`, 'RouterPlugin');
      logger.debug(`错误堆栈: ${err.stack}`, 'RouterPlugin');
    }
  }

  // 清理生成的文件
  clean() {
    logger.info('清理生成的路由文件...', 'RouterPlugin');
    this.fileManager.clean();
    logger.info('清理完成', 'RouterPlugin');
  }

  // 根据模板生成路由方法文件
  private generateBuilder(templateModel: TemplateModel) {
    logger.debug('开始生成路由构建文件', 'RouterPlugin');
    
    // 注册 Handlebars helper 函数
    Handlebars.registerHelper('and', function (a: any, b: any) {
      return a && b;
    });

    Handlebars.registerHelper('eq', function (a: any, b: any) {
      return a === b;
    });

    const builderPath = path.resolve(
      process.cwd(),
      `plugin/AutoBuildRouter/${this.config.builderTpl}`
    );
    const tpl = this.fileManager.readFile(builderPath);
    const template = Handlebars.compile(tpl);
    const output = template({
      viewList: templateModel.viewList,
    });

    const routerBuilderDir = `${this.config.modulePath}/${this.config.builderDir}`;
    this.fileManager.createDir(routerBuilderDir);
    this.fileManager.writeFile(`${routerBuilderDir}/${this.config.builderFileName}`, output);
    
    logger.debug(`路由构建文件已生成: ${routerBuilderDir}/${this.config.builderFileName}`, 'RouterPlugin');
  }

  // 以json的格式生成路由表
  private generateRouterMap(routerMap: RouterMap) {
    logger.debug('开始生成路由映射文件', 'RouterPlugin');
    
    const jsonOutput = JSON.stringify(routerMap, null, 2);
    const routerMapDir = `${this.config.modulePath}/${this.config.routerMapDir}`;
    this.fileManager.createDir(routerMapDir);
    this.fileManager.writeFile(`${routerMapDir}/${this.config.moduleName}.json`, jsonOutput);
    
    logger.debug(`路由映射文件已生成: ${routerMapDir}/${this.config.moduleName}.json`, 'RouterPlugin');
  }

  // 生成title配置文件
  private generateTitleConfig(templateModel: TemplateModel) {
    const titleConfig: { [key: string]: string } = {};

    // 收集所有字符串类型的title配置
    templateModel.viewList.forEach((view) => {
      if (view.title) {
        // 使用routerMap中的name作为key
        const routerName = `${this.config.moduleName}/${view.viewName}`;
        titleConfig[routerName] = view.title;
      }
    });

    // 如果有title配置，生成文件
    if (Object.keys(titleConfig).length > 0) {
      logger.debug(`发现 ${Object.keys(titleConfig).length} 个标题配置，开始生成标题配置文件`, 'RouterPlugin');
      
      const jsonOutput = JSON.stringify(titleConfig, null, 2);
      const routerMapDir = `${this.config.modulePath}/${this.config.routerMapDir}`;
      this.fileManager.createDir(routerMapDir);
      this.fileManager.writeFile(`${routerMapDir}/${this.config.moduleName}_title.json`, jsonOutput);
      
      logger.debug(`标题配置文件已生成: ${routerMapDir}/${this.config.moduleName}_title.json`, 'RouterPlugin');
    } else {
      logger.debug('未发现标题配置，跳过生成标题配置文件', 'RouterPlugin');
    }
  }

  // 生成Index.ets，导出路由方法
  private generateIndex() {
    logger.debug('开始生成Index.ets文件', 'RouterPlugin');
    
    const indexPath = `${this.config.modulePath}/index.ets`;
    if (!existsSync(indexPath)) {
      this.fileManager.writeFile(indexPath, '');
      logger.debug(`创建新的Index.ets文件: ${indexPath}`, 'RouterPlugin');
    }
    
    let indexContent = this.fileManager.readFile(indexPath);
    if (!indexContent.includes(' * Copyright (c) 2024 Huawei Device Co., Ltd.')) {
      const licensesPath = path.resolve(
        process.cwd(),
        `plugin/AutoBuildRouter/license.tpl`
      );
      const licenses = this.fileManager.readFile(licensesPath);
      indexContent = licenses + '\n' + indexContent;
      logger.debug('添加许可证信息到Index.ets', 'RouterPlugin');
    }
    
    const indexArr: string[] = indexContent.split('\n');
    const indexArray: string[] = [];
    indexArr.forEach((value: string) => {
      if (!value.includes(this.config?.builderDir.toString())) {
        indexArray.push(value);
      }
    });
    
    const exportStatement = `export * from './${this.config.builderDir}/${this.config.builderFileName?.replace('.ets', '')}';`;
    indexArray.push(exportStatement);
    
    this.fileManager.writeFile(indexPath, indexArray.join('\n'));
    logger.debug(`Index.ets文件已更新，添加导出语句: ${exportStatement}`, 'RouterPlugin');
  }
} 